package edu.algorithm.knn.parallel.impl;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

import edu.algorithm.knn.parallel.common.Config;
import edu.algorithm.knn.parallel.common.DataPoint;
import edu.algorithm.knn.parallel.common.FileOperator;
import edu.algorithm.knn.parallel.common.Utils;
import edu.algorithm.knn.parallel.exception.ParrallelKNNException;

/**
 * 测试数据串行KNN
 * 
 * @author liukun
 *
 */
public class KNNSerial {

	public static int K = 1000;

	public static void main(String[] args) throws FileNotFoundException, ParrallelKNNException {

		FileOperator testData = new FileOperator(Config.DATA2_FILE_PATH, Config.LABLE2_FILE_PATH);
		FileOperator originData = new FileOperator(Config.DATA_FILE_PATH, Config.LABLE_FILE_PATH);

		List<DataPoint> originalPoints = new ArrayList<DataPoint>();
		String[] trainDatas = null;
		while (originData.hasData()) {
			trainDatas = originData.next();
			DataPoint trainDataPoint = DataPoint.getOnePoint(trainDatas[0], trainDatas[1]);
			originalPoints.add(trainDataPoint);
		}
		// test data
		String[] testDatas = null;
		int counttestdata = 0;
		long begintime = System.currentTimeMillis();
		while (testData.hasData()) {
			counttestdata++;
			if (counttestdata % 100 == 0) {
				System.out.println(counttestdata);
			}
			testDatas = testData.next();
			DataPoint testDataPoint = DataPoint.getOnePoint(testDatas[0], testDatas[1]);
			PriorityQueue<DataPoint> priorityQueue = new PriorityQueue<>(K, new Comparator<DataPoint>() {
				@Override
				public int compare(DataPoint o1, DataPoint o2) {
					float dis1 = Utils.similarScore(o1, testDataPoint);
					float dis2 = Utils.similarScore(o2, testDataPoint);
					if (dis1 < dis2) {
						return -1;
					} else {
						return 1;
					}
				}
			});

			for (DataPoint trainDataPoint : originalPoints) {
				if (priorityQueue.size() < K) {
					priorityQueue.add(trainDataPoint);
				} else {
					DataPoint top = priorityQueue.peek();
					if (Utils.similarScore(top, testDataPoint) > Utils.similarScore(trainDataPoint, testDataPoint)) {
						priorityQueue.poll();
						priorityQueue.add(trainDataPoint);
					}
				}
			}
		}
		long endtime = System.currentTimeMillis();
		System.out.println("time:" + (endtime - begintime) + "mill");
	}

	public static int getLable() {
		int label = 0;

		return label;
	}
}
